;  PROGRAM: ZMO-OT05.Z80
;  AUTHOR:  Gene Weber
;  VERSION: 1.5
;  DATE:  14 Sept, 1988
;-----------------------------------------------------------------------
;	This overlay is set up for a Otrona Attache
;-----------------------------------------------------------------------
; 89/04/12 - Modified to ZMP v1.5		- George Conover
; 89/03/15 - Removed the beginning remarks to make the file
;            smaller. If you need the remarks there are in the
;            file ZMP-BLNK.Z80 			- George Conover
; 89/03/14 - Modified to ZMP v1.4		- George Conover
; 88/10/29 - modified to v .03			- Gene Weber
; 88/10/16 - Modified to ZMP v1.3		- Ken Reid
; 88/10/16 - First version of this file	       	- Gene Weber
;
;	Written by -
;	  Ron Murray, c/o Z-Node 62, 061-9-450-0200, Perth, Western Australia.
;-----------------------------------------------------------------------
NO	EQU	0
YES	EQU	NOT NO
;
; User-set variables
;
CLKSPD	EQU	4		; Processor clock speed in MHz
;
DEBUG	EQU	NO

;Set the following two equates to the drive and user area which will contain
;   ZMP's .OVR files, .CFG file, .FON file and .HLP file. Set both to zero
;   (null) to locate them on the drive from which ZMP was invoked.

OVERDRIVE	EQU	'A'	; Drive to find overlay files on ('A'-'P')
OVERUSER	EQU	0	; User area to find files

;------------------------------------------------------------------------------
;
; NOT user-set variables
;
USERDEF	EQU	0145H		; Origin of this overlay.  This address
;				;   may change with subsequent revisions
MSPEED	EQU	05CH		; Location of current baud rate. 'was' 03CH
OVSIZE	EQU	0400H		; Max size of this overlay
				;
;	.Z80			; Use z80 code -Attn! uncomment to use Macro-80
;	ASEG			; Absolute     -Attn! same, also take out '-'
				;     in the over-lay name. M80 don't like it.
	 IF	DEBUG
	ORG	100H		; So you can debug it with CEBUG, ZSID,
;				;   etc.
	 ELSE
	ORG	USERDEF
	 ENDIF			; DEBUG
;
ESC	EQU	1BH
CTRLQ	EQU	11H
CR	EQU	0DH
LF	EQU	0AH
BDOS	EQU	5
				;
PORT	EQU	0F0H		; Attache base port (data or status)
MDCTL1	EQU	PORT+1		; Modem control port
MDDATP	EQU	PORT		; Modem data port
MDRCV	EQU	01H		; Modem receive ready
MDSND	EQU	04H		; Modem send ready bit DAV
MDTXE	EQU	01H		; Modem send buffer empty, holding
				; buffer empty
BAUDA	EQU	57H		; CTC port/Cmd word for Otrona  baudrate
;
; Jump table for the overlay: do NOT change this
;
CODEBGN	EQU	$
;
JUMPTAB:
	JP	SCRNPR		; Screen print
	JP	MRD		; Modem read with timeout
	JP	MCHIN		; Get a character from modem
	JP	MCHOUT		; Send a character to the modem
	JP	MORDY		; Test for tx buffer empty
	JP	MIRDY		; Test for character received
	JP	SNDBRK		; Send break
	JP	CURSADD		; Cursor addressing
	JP	CLS		; Clear screen
	JP	INVON		; Inverse video on
	JP	INVOFF		; Inverse video off
	JP	HIDE		; Hide cursor
	JP	SHOW		; Show cursor
	JP	SAVECU		; Save cursor position
	JP	RESCU		; Restore cursor position
	JP	MINT		; Service modem interrupt
	JP	INVEC		; Initialise interrupt vectors
	JP	DINVEC		; De-initialise interrupt vectors
	JP	MDMERR		; Test uart flags for error
	JP	DTRON		; Turn DTR on
	JP	DTROFF		; Turn DTR OFF
	JP	INIT		; Initialise uart
	JP	WAIT		; Wait seconds
	JP	MSWAIT		; Wait milliseconds
	JP	USERIN		; User-defined entry routine
	JP	USEROUT		; User-defined exit routine
	JP	GETVARS		; get system variables
  	JP	SETPORT		; Set port (0 or 1)
;
; Spare jumps for compatibility with future versions
;
	JP	SPARE		; spare for later use
	JP	SPARE		; Spare for later use
	JP	SPARE		; Spare for later use
	JP	SPARE		; Spare for later use
	JP	SPARE		; Spare for later use
	JP	SPARE		; Spare for later use
;
;Screen print function
SCRNPR:
	CALL	PRINT
	DB	'Zmodem v1.5 overlay for Otrona Attache '
	DB	' v0.3  dated  29 October 1988',CR,LF
	DB	'Over-lay & Assembly by: Gene Weber.',CR,LF
	DB	'                        Houston, Texas.',CR,LF
	DB	'                        Ph.# 713/449-6402',CR,LF,LF
	DB	'*** Print screen *** function is not supported.',CR,LF,0
SPARE:
	RET		; This ret used by both scrnpr & spare
;
;
; User-defined entry routine
;
USERIN:	RET
;
; User-defined exit routine
;
USEROUT:RET
;
; Get a character from the modem: return in HL
; It is not necessary to test for status
;
MCHIN:	PUSH	BC
;
			; <-= Insert Otrona Attache code here
;
	IN	A,(MDDATP)	; Get the character in A
;
			; <-= End of your code
;
	LD	L,A		; Put in HL
	LD	H,0
	OR	A		; Set/clear Z
	POP	BC
	RET
;
;Send a character to the modem
;
MCHOUT:	LD	HL,2		; Get the character
	ADD	HL,SP
	LD	A,(HL)		; In A
;
			; <-= Insert Otrona Attache code here
;
	PUSH	BC
	LD	C,A
;
MCHOUT1:IN	A,(MDCTL1)
	AND	MDSND
	JR	Z,MCHOUT1
	LD	A,C
	OUT	(MDDATP),A
	POP	BC
;
			; <-= End of Otrona Attache code
;
	RET			; Done
;
;Test for output ready: return TRUE (1) in HL if ok
;
MORDY:	DS	0
;
			; <-= Insert Otrona Attache code here
;
	IN	A,(MDCTL1)
	AND	MDTXE
	JR	Z,MORDYX
	LD	L,1
	LD	H,0
;
MORDYX:	DS	0
;
			; <-= End of Otrona Attache code
;
	LD	A,L		; Set/clear Z
	OR	A
	RET
;
;Test for character at modem: return TRUE (1) in HL if so
;
MIRDY:	DS	0
;
			; <-= Insert Otrona Attache code here
;
	IN	A,(MDCTL1)
	AND	MDRCV
	JR	Z,MIRDY1
	LD	L,1
	JR	MIRDYX
;
MIRDY1:	LD	L,0
;
MIRDYX:	LD	H,00H
;
			; <-= End of Otrona Attache code
;
	LD	A,L		; Set/clear Z
	OR	A
	RET
;
;Send a break to the modem: leave empty if your system can't do it
;
SNDBRK:	DS	0
;
			; <-= Insert Otrona Attache code here
;
	LD	A,5
	OUT	(MDCTL1),A	; Send to the status port
	LD	A,0F8H		; DTR normal, send break tone
	OUT	(MDCTL1),A
;
			; <-= End of Otrona Attache code
;
	LD	HL,300
	CALL	WAITHLMS	; Wait 300 milliseconds
;
			; <-= Insert Otrona Attache code here
;
	LD	A,5		; Restore normal, 8 bits, DTR on, etc.
	OUT	(MDCTL1),A
	LD	A,0E8H
	OUT	(MDCTL1),A
;
			; <-= Insert Otrona Attache code here
;
	RET
;
; Test UART flags for error: return TRUE (1) in HL if error
;
MDMERR:	DS	0
;
			; <-= Insert Otrona Attache code here
;
	LD	A,010H		; Register 0, reset interrupts
	OUT	(MDCTL1),A
	IN	A,(MDCTL1)
;
			; <-= End of Otrona Attache code
;
	LD	A,L		; Set/clear Z
	OR	A
	RET
;
; Turn DTR (and optionally RTS) ON
;
DTRON:	DS	0
;
			; <-= Insert Otrona Attache code here
;
	LD	A,05H
	OUT	(MDCTL1),A
	LD	A,0E8H
	OUT	(MDCTL1),A
;
			; <-= End of Otrona Attache code
;
	RET
;
; Turn DTR ( and RTS?) OFF
;
DTROFF:	DS	0
;
			; <-= Insert Otrona Attache code here
;
	LD	A,05H
	OUT	(MDCTL1),A
	LD	A,078H
	OUT	(MDCTL1),A
;
			; <-= End of Otrona Attache code
;
	RET
;
;Initialise the UART
;
INIT:	LD	HL,2		; Get parameters
	ADD	HL,SP
	EX	DE,HL
	CALL	GETPARM		; In HL
	LD	(BRATE),HL	; Baud rate
	CALL	GETPARM
	LD	(PARITY),HL	; Parity
	CALL	GETPARM
	LD	(DATA),HL	; Data bits
	CALL	GETPARM
	LD	(STOP),HL	; Stop bits
;
			; <-= Insert Otrona Attache code here
;
	PUSH	BC
	LD	A,0		; Select register
	OUT	(MDCTL1),A
	LD	A,018H		; Throw out of mode
	OUT	(MDCTL1),A
	LD	A,04H		; Select register
	OUT	(MDCTL1),A
	LD	A,044H		; Set ASCII parameters (44=1, 4C=2 stop)
	OUT	(MDCTL1),A
	LD	A,03H		; Select register
	OUT	(MDCTL1),A
	LD	A,0C1H		; Enable receive
	OUT	(MDCTL1),A
	LD	A,05H		; Select register
	OUT	(MDCTL1),A
	LD	A,0EAH		; Enable send, 'DTR', RTS'
	OUT	(MDCTL1),A
;
        LD	A,(BRATE)	; Load default baudrate
;
	CP	1		; 300 bps
	JP	Z,OK300
	CP	5		; 1200 bps
	JP	Z,OK1200
	CP	6		; 2400 bps
	JP	Z,OK2400
	CP	7		; 4800bps
	JP	Z,OK4800
	CP	8		; 9600 bps
	JP	Z,OK9600
	CP	9		; 19.2k bps
	JP	Z,OK19200
	JR	SETBRX		; Not valid
;
OK300:	LD	A,1		; MSPEED 300 bps value
	LD	B,BD300
	JP	LOADBD
;
OK1200:	LD	A,5
	LD	B,BD1200
	JP	LOADBD
;
OK2400:	LD	A,6
	LD	B,BD2400
	JP	LOADBD
;
OK4800:	LD	A,7
	LD	B,BD4800
	JP	LOADBD
;
OK9600:	LD	A,8
	LD	B,BD9600
	JP	LOADBD
;
OK19200:LD	A,9
	LD	B,BD19200
;
LOADBD:	LD	(MSPEED),A	; Change baudrate
	LD	A,B		; Put Baudrate from reg B into reg A
	OUT	(BAUDA),A	; Combine reg A with CTC cmd word
	LD	A,(BRATE)	; Tell zmp it's ok
	LD	(MSPEED),A
;
SETBRX:	POP	BC
;
			; <-= Insert Otrona Attache code here
	XOR	A
	LD	(MSPEED),A 	; CLEAR IT
;
			; <-= End of Otrona Attache code
	RET
;
BD300	EQU	4
BD1200	EQU	5
BD2400	EQU	6
BD4800	EQU	8
BD9600	EQU	9
BD19200	EQU	10
				; Using values below
;
	RET
;
BRATE:	DS	2		; Baud rate:
				; 0 = 110 baud	1 = 300 baud	2 = 450 baud
				; 3 = 600 baud	4 = 710 baud	5 = 1200 baud
				; 6 = 2400 baud 7 = 4800 baud	8 = 9600 baud
				; 9 = 19200 baud
PARITY:	DS	2		; Parity (will be 'N', 'E' or 'O')
DATA:	DS	2		; Data bits (will be 7 or 8)
STOP:	DS	2		; Stop bits (will be 1 or 2)
;
;
; Set the port. ZMP supplies either 0 or 1 as a parameter.
;
setport:
	ld	hl,2		; get port number
	add	hl,sp
	ex	de,hl
	call	getparm		; in HL (values are 0 and 1)

				; <== Insert your own code here

				; <== End of your own code
	ret
;-----------------------------------------------------------------------
;
; Video terminal sequences: these are for ADM-3A: Modify as you wish
;
; Cursor addressing
;
CURSADD:LD	HL,2		; Get parameters
	ADD	HL,SP
	EX	DE,HL
	CALL	GETPARM		; In HL
	LD	(ROW),HL	; Row
	CALL	GETPARM
	LD	(COL),HL	; Column
;
			; <-= Insert Otrona Attache code here,
; 			using values in row and column
;
	CALL	PRINT
	DB	ESC,'=',0	; ADM-3A leadin
	LD	A,(ROW)		; Row first
	ADD	A,' '		; Add offset
	CALL	COUT
	LD	A,(COL)		; Same for column
	ADD	A,' '
	CALL	COUT
;
			; <-= end of Otrona Attache code
;
	RET
;
ROW:	DS	2		; Row
COL:	DS	2		; Column
;
;Clear screen
;
CLS:	CALL	PRINT
	DB	01AH,0
	RET
;
; Inverse video on
;
INVON:	CALL	PRINT
	DB	ESC,'U&',0
	RET
;
; Inverse video off
;
INVOFF:	CALL	PRINT
	DB	ESC,'U ',0
	RET
;
; Turn off cursor
;
HIDE:	CALL	PRINT
	DB	ESC,'c',0
	RET
;
; Turn on cursor
;
SHOW:	CALL	PRINT
	DB	ESC,'d',0
	RET
;
; Save cursor position
;
SAVECU:	RET
;
; Restore cursor position
;
RESCU:	RET
;
;-----------------------------------------------------------------------
;
; Service modem interrupt
;
MINT:	RET			; My system doesn't need this
;
; Initialise interrupt vectors
;
INVEC:	RET			; Ditto
;
; De-initialise interrupt vectors
;
DINVEC:	RET			; Ditto
;
;------------------- End of user-defined code --------------------------
;		 Do not change anything below here
;
; Modem character test for 100 ms
;
MRD:	PUSH	BC		; Save BC
	LD	BC,100		; Set limit
;
MRD1:	CALL	MIRDY		; Char at modem?
	JR	NZ,MRD2		; Yes, exit
	LD	HL,1		; Else wait 1 ms
	CALL	WAITHLMS
	DEC	BC		; Loop till done
	LD	A,B
	OR	C
	JR	NZ,MRD1
	LD	HL,0		; None there, result=0
	XOR	A
;
MRD2:	POP	BC
	RET
;
; Inline print routine: destroys A and HL
;
PRINT:	EX	(SP),HL		; Get address of string
;
PLOOP:	LD	A,(HL)		; Get next
	INC	HL		; Bump pointer
	OR	A		; Done if zero
	JR	Z,PDONE
	CALL	COUT		; Else print
	JR	PLOOP		; And loop
;
PDONE:	EX	(SP),HL		; Restore return address
	RET			; And quit
;
; Output a character in A to the console
;
COUT:	PUSH	BC		; Save registers
	PUSH	DE
	PUSH	HL
	LD	E,A		; Character to E
	LD	C,2
	CALL	BDOS		; Print it
	POP	HL
	POP	DE
	POP	BC
	RET
;
; Wait(seconds)
;
WAIT:	LD	HL,2
	ADD	HL,SP
	EX	DE,HL		; Get delay size
	CALL	GETPARM
;				; Fall thru to...
; Wait seconds in HL
;
WAITHLS:PUSH	BC		; Save BC
	PUSH	DE		; DE
	PUSH	IX		; And IX
	LD	IX,0		; Then point IX to 0
;				;   so we don't upset memory-mapped I/O
;
; Calculate values for loop constants. Need to have two loops to avoid
; 16-bit overflow with clock speeds above 9 MHz.
;
OUTERVAL EQU	(CLKSPD	/ 10) +	1
;
INNERVAL EQU	(6667 /	OUTERVAL) * CLKSPD
;
WAIT10:	LD	B,OUTERVAL
;
WAIT11:	LD	DE,INNERVAL
;
WAIT12:	BIT	0,(IX)		; Time-wasters
	BIT	0,(IX)
	BIT	0,(IX)		; 20 T-states each
	BIT	0,(IX)
	BIT	0,(IX)
	BIT	0,(IX)
	DEC	DE
	LD	A,E
	LD	A,D
	OR	E
	JR	NZ,WAIT12	; 150 T-states per inner loop
	DJNZ	WAIT11		; Decrement outer loop
	DEC	HL		; Ok, decrement count in HL
	LD	A,H
	OR	L
	JR	NZ,WAIT10
	POP	IX		; Done -- restore IX
	POP	DE		; DE
	POP	BC		; And BC
	RET
;
; Wait milliseconds
;
MSWAIT:	LD	HL,2
	ADD	HL,SP
	EX	DE,HL		; Get delay size
	CALL	GETPARM
;
; Wait milliseconds in HL
;
WAITHLMS:
	PUSH	DE
;
W1MS0:	LD	DE,39 *	CLKSPD
;
W1MS1:	DEC	DE
	LD	A,D
	OR	E
	JR	NZ,W1MS1
	DEC	HL
	LD	A,H
	OR	L
	JR	NZ,W1MS0
	POP	DE
	RET
;
; Get next parameter from (DE) into HL
;
GETPARM:EX	DE,HL		; Get address into HL
	LD	E,(HL)		; Get low
	INC	HL
	LD	D,(HL)		; Then hihi
	INC	HL		; Bump for next
	EX	DE,HL		; Result in HL, address still in DE
	RET
;
;Get address of user-defined variables
;
GETVARS:
	LD	HL,USERVARS
	RET
USERVARS:
	DW	OVERDRIVE	; .OVR etc. drive/user
	DW	OVERUSER
;
	 IF	($ - CODEBGN) GT OVSIZE
TOOBIG:	JP	ERRVAL		; Overlay is too large
	 ENDIF
;
	END
